import marimo

__generated_with = "0.13.7"
app = marimo.App()


@app.cell
def _(mo):
    mo.md(rf"""# 数据操作""")
    return


@app.cell
def _():
    import marimo as mo
    return (mo,)


@app.cell
def _(mo):
    mo.md(rf"""## 入门""")
    return


@app.cell
def _(mo):
    mo.md(r"### 包导入")
    return


@app.cell
def _():
    import torch
    return (torch,)


@app.cell
def _(mo):
    mo.md(r"### 1维张量")
    return


@app.cell
def _(torch):
    x = torch.arange(12)
    x
    return (x,)


@app.cell
def _(mo):
    mo.md(r"### 元素个数")
    return


@app.cell
def _(x):
    x.numel() # number of element
    return


@app.cell
def _(mo):
    mo.md(r"### 形状")
    return


@app.cell
def _(x):
    x.shape
    return


@app.cell
def _(mo):
    mo.md(r"### 重新组织形状")
    return


@app.cell
def _(x):
    X = x.reshape(3,4)
    X
    return (X,)


@app.cell
def _(mo):
    mo.md(r"### 生成指定形状的1")
    return


@app.cell
def _(torch):
    torch.ones(2, 3, 4)
    return


@app.cell
def _(mo):
    mo.md(r"### 生成指定形状的0")
    return


@app.cell
def _(torch):
    torch.zeros(2, 3, 4)
    return


@app.cell
def _(mo):
    mo.md(
        r"""
        ### 随机生成指定形状的数字
        值从均值为0，方差为1的高斯分布随机抽取。
        """
    )
    return


@app.cell
def _(torch):
    torch.randn(3, 4)
    return


@app.cell
def _(mo):
    mo.md(r"### 为张量每个元素赋值")
    return


@app.cell
def _(torch):
    torch.tensor([[2, 3, 4], [4, 5, 6], [7, 8, 9]])
    return


@app.cell
def _(mo):
    mo.md(r"## 运算符")
    return


@app.cell
def _(torch):
    a = torch.tensor([1.0, 2, 4, 8])
    b = torch.tensor([2, 2, 2, 2])
    a + b, a - b, a * b, a / b, a**b
    return (a,)


@app.cell
def _(a, torch):
    torch.exp(a)
    return


@app.cell
def _(mo):
    mo.md(r"### 张量连结")
    return


@app.cell
def _(torch):
    c = torch.arange(12).reshape(3, 4)
    d = torch.tensor([[2, 3, 4, 1], [4, 5, 6, 1], [7, 8, 9, 1]])
    torch.cat([c, d], dim=1), torch.cat([c, d], dim=0)
    return c, d


@app.cell
def _(torch):
    c1 = torch.arange(12).reshape(1,2, 6)
    d1 = torch.arange(6).reshape(1,1, 6)
    c1,d1,torch.cat([c1,d1], dim=1).shape
    return


@app.cell
def _(mo):
    mo.md(r"cat操作要求除连结维度外，其他所有维度的维数必须相同。")
    return


@app.cell
def _(mo):
    mo.md(r"### 判断相等")
    return


@app.cell
def _(c, d):
    c == d
    return


@app.cell
def _(mo):
    mo.md(r"### 求和")
    return


@app.cell
def _(c):
    c.sum()
    return


@app.cell
def _(mo):
    mo.md(
        r"""
        ## 广播机制
        1. 形状不相同，小的维度补1；
        2. 维度不相同，但含1，则可广播；
        3. 维度不相同，且不含1，则无法广播，原因是较小维度不能整数倍复制至大维度。
        """
    )
    return


@app.cell
def _(torch):
    e = torch.arange(3).reshape(3, 1)
    f = torch.arange(2).reshape(1, 2)
    e,f
    return e, f


@app.cell
def _(mo):
    mo.md(r"形状不相同，一般情况下无法进行操作，但是python提供了一种方法，就是使用broadcasting，broadcasting就是让两个数组具有相同的形状，然后进行操作。")
    return


@app.cell
def _(e, f):
    e+f
    return


@app.cell
def _(mo):
    mo.md(r"e复制列，f复制行。")
    return


@app.cell
def _(mo):
    mo.md(r"## 索引和切片")
    return


@app.cell
def _(X):
    X,X[-1],X[1:3]
    return


@app.cell
def _(X):
    X[1,2]=9
    X
    return


@app.cell
def _(X):
    X[0:2,:]=12
    X
    return


@app.cell
def _(mo):
    mo.md(r"## 节省内存")
    return


@app.cell
def _(X):
    Y = X[:]
    print(Y)
    before = id(Y)
    Y = X + Y
    after = id(Y)
    before == after
    return (Y,)


@app.cell
def _(X, Y, torch):
    Z = torch.zeros_like(X)
    print("id(Z)", id(Z))
    Z[:] = X + Y
    print("id(Z)", id(Z))
    return


@app.cell
def _(mo):
    mo.md(r"## 转换为其他python对象")
    return


@app.cell
def _(X, torch):
    A = X.numpy()
    B = torch.tensor(A)
    type(A), type(B), id(A), id(B)
    return


@app.cell
def _(mo):
    mo.md(r"### tensor转为标量")
    return


@app.cell
def _(mo):
    mo.md(r"只有大小为1的张量可以转换为Python标量")
    return


@app.cell
def _(torch):
    torch.tensor([1]).item()
    return


@app.cell
def _(mo):
    mo.md(r"## 练习")
    return


@app.cell
def _(mo):
    mo.md(r"1. 运行本节中的代码。将本节中的条件语句X == Y更改为X < Y或X > Y，然后看看你可以得到什么样的张量。")
    return


@app.cell
def _(X, Y):
    X>Y,X<Y
    return


@app.cell
def _(mo):
    mo.md(r"2. 用其他形状（例如三维张量）替换广播机制中按元素操作的两个张量。结果是否与预期相同？")
    return


@app.cell
def _(torch):
    t1 = torch.arange(18).reshape(3, 3, 2)
    t2 = torch.arange(6).reshape(1, 4, 2)
    t1 + t2
    return


if __name__ == "__main__":
    app.run()
